package dev.http.urlconnection;

/**
 * Author:   RunAtWorld
 * Date:     2021/3/30 0:49
 */

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Map;

/**
 * 使用 Http 的 UrlConnection
 */
@Slf4j
public class HttpUrlConnectionUtil {

    /**
     * 发送GET请求
     *
     * @param url
     * @param headers
     * @return
     */
    public static String sendGetRequest(String url, Map headers) {
        InputStream is = null;
        BufferedWriter writer = null;
        OutputStream output = null;
        HttpURLConnection conn = null;
        try {
            URL newUrl = new URL(url);
            conn = (HttpURLConnection) newUrl.openConnection();
            log.info("url:{}", conn.getURL());
            // 设置连接主机服务器的超时时间：15秒
            conn.setConnectTimeout(15 * 1000);
            // 设置读取远程返回的数据超时时间为10秒
            conn.setReadTimeout(10 * 1000);
            // 设置请求方式GET
            conn.setRequestMethod("GET");
            // Post请求不能使用缓存
            conn.setUseCaches(false);
            // 接受输入流
            conn.setDoInput(false);
            // 启动输出流，当需要传递参数时需要开启
            conn.setDoOutput(true);
            // 添加Header
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "application/json");
            HttpURLConnection finalConn = conn;
            if (headers != null) {
                headers.forEach((k, v) -> {
                    finalConn.setRequestProperty(k.toString(), v.toString());
                });
            }

            // 发起请求
            conn.connect();

            // 添加请求参数，注意：如果是GET请求，参数要写在URL中
            output = conn.getOutputStream();
            writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
            // 写入参数 用&分割
            // writer.write("demo=1");
            writer.flush();

            // 状态码
            int code = conn.getResponseCode();
            log.info("http code:{}", code);
            if (code == 200) {
                is = conn.getInputStream();
                String result = readInputStreamByReader(is);
                return result;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != output) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            conn.disconnect();
        }
        return null;
    }

    /**
     * 发送Post请求
     *
     * @param url
     * @param headers
     * @param body
     * @return
     */
    public static String sendPostRequest(String url, Map headers, Object body) {
        InputStream is = null;
        BufferedWriter writer = null;
        OutputStream output = null;
        HttpURLConnection conn = null;
        try {
            URL newUrl = new URL(url);
            conn = (HttpURLConnection) newUrl.openConnection();
            log.info("url:{}", conn.getURL());
            // 设置读去超时时间为10秒
            conn.setReadTimeout(10 * 1000);
            // 设置连接超时为10秒
            conn.setConnectTimeout(15 * 1000);
            // 设置请求方式,GET,POST
            conn.setRequestMethod("POST");
            // Post请求不能使用缓存
            conn.setUseCaches(false);
            // 接受输入流
            conn.setDoInput(true);
            // 启动输出流，当需要传递参数时需要开启
            conn.setDoOutput(true);
            // 添加Header
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Content-Type", "application/json");
            HttpURLConnection finalConn = conn;
            if (headers != null) {
                headers.forEach((k, v) -> {
                    finalConn.setRequestProperty(k.toString(), v.toString());
                });
            }

            // 添加Body
            String bodyJson = JSON.toJSONString(body);
            log.info("req body:{}", bodyJson);

            // 发起请求
            conn.connect();
            output = conn.getOutputStream();
            // 写入参数
            writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
            writer.write(bodyJson);

            // 状态码
            int code = conn.getResponseCode();
            log.info("http code:{}", code);
            if (code == 200) {
                is = conn.getInputStream();
                String result = readInputStreamByReader(is);
                return result;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != output) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 断开与远程地址url的连接
            conn.disconnect();
        }
        return null;
    }

    /**
     * 把输入流的内容转化成字符串
     *
     * @param is
     * @return
     */
    public static String readInputStreamByReader(InputStream is) {
        StringBuffer sbf = new StringBuffer();
        // 获取服务端响应，通过输入流来读取URL的响应
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
            String line = null;
            while ((line = reader.readLine()) != null) {
                sbf.append(line);
                sbf.append("\r\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("IOException:{}", e.getMessage());
        }
        return sbf.toString();
    }
}